package com.sensePlusVR.utils;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.annotation.SuppressLint;
import android.content.Context;

import com.sensePlusVR.activity.listener.NetworkEvent;
import com.sensePlusVR.application.VRApplication;
import com.sensePlusVR.bean.CollectionItem;
import com.sensePlusVR.bean.GameItem;
import com.sensePlusVR.bean.GameUrl;
import com.sensePlusVR.buriedpoint.GameDownloadBP;
import com.sensePlusVR.receiver.NetworkReceiver;
import com.sensePlusVR.utils.DownloadBatchUrl.DownloadCallBack;
import com.sensePlusVR.widget.dialog.MemoryLessDialog;

@SuppressLint("UseSparseArrays")
public class GameDownload {
	static private final String TAG = "GameDownload";

	// private Map<String, String> gameUrlMap;
	static private int FailtRetry = 100;
	static public int GameDownLoadStatDoing = 1;
	static public int GameDownLoadStatDone = 2;
	static public int GameDownLoadStatNeedDownload = 3;
	static public int GameDownLoadStatClicked = 4;
	
	/*gameDownload 返回值*/
	static final public int GameDownLoadByWifi = 0x01;
	static final public int GameDownLoadByCelluar = 0x02;
	static final public int GameDownLoadNotAllowCelluar = 0x10;
	static final public int GameDownLoadNoNetwork = 0x11;
	static final public int GameDownLoadItemExsit = 0x12;
	static final public int GameDownLoadItemNULL = 0x13;
	
	static Object lock = new Object();
	static Object nLock = new Object();
	
	static ListMap<Integer, DownloadTask> tasks = new ListMap<Integer, DownloadTask>();
	static private int NetWorkStatus = NetworkUtils.STATE_CONNECT_WIFI;
	static private boolean AllowCelluer = false;
	static private Map<String, NetWorkNotify> networkCallBack = new HashMap<String, NetWorkNotify>();
	static Object notifyLock = new Object();
	
	static NetworkEvent netEvent = null;
	
	public static void init(Context context){
		NetWorkStatus = NetworkUtils.getNetConnectState(context);
		AllowCelluer = CommonData.getMobileNetSwitch(context);
		netEvent = new NetworkEvent(){
			public void onNetChange(int netwrokState){
				networkChanged(netwrokState);
			}
		};
		NetworkReceiver.setNetworkChangeNotify(netEvent, TAG);
	}
	
	/*回调给界面*/
	private static void NotifyNetworkChanged(int status){
		synchronized(notifyLock){
			for (String key : networkCallBack.keySet()){
				NetWorkNotify netnotify = networkCallBack.get(key);
				netnotify.notify(status);
			}
		}
	}
	
	/*设置网络改变的回调，n=null取消回调 */
	public static void setNetWorkNotify(String key, NetWorkNotify n){
		synchronized(notifyLock){
			if (n != null)
				networkCallBack.put(key, n);
			else
				networkCallBack.remove(key);
		}
	}
	
	/*网络发生改变的时候调用*/
	public static void networkChanged(int network){
		if (network == NetWorkStatus)
			return;
		int prevCanDown = canDownloadByNetwork(NetWorkStatus, AllowCelluer);
		int currCanDown = canDownloadByNetwork(network, AllowCelluer);
		NetWorkStatus = network;
		changeDownloadByNetWork(prevCanDown, currCanDown);
	}
	
	/*切换4G开关的时候调用*/
	public static void allowCelluerChanged(boolean allow){
		if (allow == AllowCelluer)
			return;
		int prevCanDown = canDownloadByNetwork(NetWorkStatus, AllowCelluer);
		int currCanDown = canDownloadByNetwork(NetWorkStatus, allow);
		AllowCelluer = allow;
		changeDownloadByNetWork(prevCanDown, currCanDown);
	}
	
	/*第一次进入页面的时候，需要手动的获取一次当前是否允许下载的状态*/
	public static int getDownloadStauts(){
		return canDownloadByNetwork(NetWorkStatus, AllowCelluer);
	}
	
	private static void changeDownloadByNetWork(int prevCan, int currCan){
		MyLog.d(TAG, "test debug prevCan : " + prevCan + " currCan : " + currCan);
		/*以前停止下载了，现在可以下载*/
		if (prevCan >= GameDownLoadNotAllowCelluar && currCan < GameDownLoadNotAllowCelluar){
			restartAllByNetWorkAvalible();
		}
		/*以前正在下载了，现在停止下载*/
		if (prevCan < GameDownLoadNotAllowCelluar && currCan >= GameDownLoadNotAllowCelluar){
			stopAllByNetWorkNotAvalible();
		}
		///
		NotifyNetworkChanged(currCan);
	}
	
	/*判断是否可以开始下载*/
	private static int canDownloadByNetwork(int network, boolean allowCelluar){
		if (network == NetworkUtils.STATE_CONNECT_WIFI)/*wifi*/
			return GameDownLoadByWifi;
		if (network == NetworkUtils.STATE_CONNECT_MOBILE) {//celluar
			if (allowCelluar){
				return GameDownLoadByCelluar;
			}
			return GameDownLoadNotAllowCelluar;
		}
		return GameDownLoadNoNetwork;
	}
	
	/**获取当前下载任务中数量*/
	public static int getDownloadTaskSize(){
		return tasks.getList().size();
	}
	
	//获取下载根目录
	public static String getRootPath(GameItem gameItem){
		return gameItem.getType().equals(Constant.TYPE_LIKEREAL)||gameItem.getType().equals(Constant.TYPE_DEMO_LIKEREAL)?getVirtualGameCacheDir():getRealGameCacheDir(gameItem.getTitle());
	}
	
	//获取下载根目录
	public static String getRootPathCorrected(GameItem gameItem){
		 List<String> urls = GameUrls(gameItem);
		    if (urls == null || urls.size() == 0)
		      return getRealGameCacheDir(gameItem.getTitle());
		    String oneUrl = urls.get(0);
		    GameUrl saved = GameUrl.query(oneUrl);
		    if (saved == null){
		      return getRealGameCacheDir(gameItem.getTitle());
		    }
		    String savedPath = saved.getSavePath();
		    File f = new File(savedPath);
		    return f.getParent();
	}

	
	private static String getVirtualGameCacheDir() {
		return FileUtils.getExternalFilesDir(VRApplication.getAppContext()) + "/unReal";
	}
	
	private static String getRealGameCacheDir(String name){
		String gameDir = name.replaceAll("\\s*", "");
		return FileUtils.getExternalFilesDir(VRApplication.getAppContext()) + "/real/"+gameDir;
	}
		
	static public String getGameConfig(GameItem gameItem) {
		
		boolean isRealGame = gameItem.getType().equals(Constant.TYPE_DEMO_REAL)||gameItem.getType().equals(Constant.TYPE_REAL);
		String gameConfig = "";
		
		if (gameItem != null) {
			String gameUrl = gameItem.getGameurl();
			if(gameUrl != null){
				String[] fileNames = gameUrl.split(",");
				for (String fileName : fileNames) {
					if(fileName.endsWith("_script") || fileName.endsWith(".json")){
						gameConfig = getRootPathCorrected(gameItem) + File.separator + fileName;
						if(!isRealGame){
							
							gameConfig = "file://"+gameConfig;
						}
						
						break;	
					}
				}
			}
		}
		
		MyLog.d(TAG, "gameConfig : " + gameConfig);
		
		return gameConfig;
	}

	static public List<String> GameUrls(GameItem gameItem) {
		List<String> gameList = new ArrayList<String>();
		if (gameItem != null) {
			String gameUrl = gameItem.getGameurl();
			if(gameUrl != null){
				String[] urls = gameUrl.split(",");
				String prefix = gameItem.getPrefix();
				for (String url : urls) {
					gameList.add(prefix+url);
				}	
			}
		}
		return gameList;
	}
	
	/**
	 * 获取游戏资源
	 * @param gameItem
	 * @return
	 */
	private static List<String> GameRes(GameItem gameItem){
		
		List<String> resList = new ArrayList<String>();
		
		if (gameItem != null) {
			String gameUrl = gameItem.getGameurl();
			String[] urls = gameUrl.split(",");
			for (String url : urls) {
				resList.add(url);
			}
		}
		return resList;
	}
	

	public static int downloadGame(GameItem gameItem) {
		
		if (gameItem == null) {
			return GameDownLoadItemNULL;
		}
		if (tasks.containsKey(gameItem.getId())){
			MyLog.d(TAG, "game id "+gameItem.getId() + " is alreay downloading, maybe some errors!");
			return GameDownLoadItemExsit;
		}
		recordDownloadStartTime(gameItem);

		GameDownloadBP.getInstants().saveDownloadAddBuried(gameItem);
		//开始下载
		synchronized (lock){
			return doDownload(gameItem);
		}
	}
	
	static private void recordDownloadStartTime(GameItem gameItem){
		CollectionItem clcItem = CollectionItem.query(gameItem.getId());

		if(clcItem!=null){
			
			clcItem.setDownloadTime(new Date().getTime());
			
			clcItem.setDownloadState(CollectionItem.DownloadDoing);
			
			CollectionItem.saveOrUpdate(clcItem);
			
		}
	}
	
	static private DownloadTask doAddPendingQueue(GameItem gameItem)
	{
		List<String> urlList = GameUrls(gameItem);
		
		String savePath = getRootPath(gameItem);
		
		DownloadTask task = new DownloadTask(gameItem,savePath,urlList);
		tasks.add(gameItem.getId(), task);
		task.setReTry(0);
		task.setMaxRetry(FailtRetry);
		return task;
	}
	
	static private int doDownload(final GameItem gameItem){
		
		DownloadTask task = doAddPendingQueue(gameItem);
		int downstatus = canDownloadByNetwork(NetWorkStatus, AllowCelluer);
		/* 如果网络允许， 加入下载队列，如果队列为空，立即开始下载 */
		if (downstatus < GameDownLoadNotAllowCelluar)
			DownloadBatchUrl.getInstants().addTask(task);
		
		new Thread(){
			public void run(){
				gameDownNotify(gameItem);
			}
		}.start();
		return downstatus;
	}
	
	static private void stopAllByNetWorkNotAvalible(){
		MyLog.d(TAG, "test debug stopAllByNetWorkNotAvalible");
		DownloadBatchUrl.getInstants().stopAll();
		synchronized (lock){
			for (Map.Entry<Integer, DownloadTask> task : tasks.entrySet()){
				DownloadTask download = task.getValue();
				download.setDownloadState(DownloadTask.DownloadPending);
			}
		}
	}
	
	static private void restartAllByNetWorkAvalible(){
		MyLog.d(TAG, "test debug restartAllByNetWorkAvalible");
		synchronized (lock){
			List<DownloadTask> tasklist = tasks.getList();
			for (DownloadTask download : tasklist){
				download.reset();
				download.setReTry(0);
				download.setMaxRetry(FailtRetry);
				download.setDownloadState(DownloadTask.DownloadDoing);
				DownloadBatchUrl.getInstants().addTask(download);
			}
		}
	}
	
	static public boolean isDownloadWaiting(GameItem item){
		if(item!=null&&tasks.containsKey(item.getId())){
			
			DownloadTask task = tasks.get(item.getId());
			
			return task.isWaiting();
			
		}
		
		
		return true;
		
	}
	
	/**
	 * 取消所有正在下载Item
	 */
	static public void cancelAllDownloading(){
		 for (Map.Entry<Integer, DownloadTask> task : tasks.entrySet()) {
			System.out.println("key= " + task.getKey() + " and value= " + task.getValue());
			//Integer key = task.getKey();
			DownloadTask value = task.getValue();
			value.setDownloadState(DownloadTask.DownloadCancel);
			DownloadBatchUrl.getInstants().removeTask(value);
			//tasks.remove(key);
		}
		 tasks.clear();
	}
	
	/**
	 * 暂停中取消下载（因为暂停已经从task中remove了，所以只更新CollcetionItem状态）
	 * @param clcItem
	 */
	static public void pauseCancelDownload(CollectionItem clcItem){
		synchronized (lock) {
			
			clcItem.setDownloadState(CollectionItem.DownloadNone);
			
			CollectionItem.saveOrUpdate(clcItem);
			
		}
	}
	
	/**
	 * 取消下载
	 * @param item
	 */
	static public void cancelDownload(GameItem item,CollectionItem clcItem){
		
		MyLog.e(TAG, "cancelDownload..");
		
		synchronized (lock) {
			
			if(item!=null&&tasks.containsKey(item.getId())){
				MyLog.e(TAG, "do cancelDownload..");
				DownloadTask task = tasks.get(item.getId());
				
				task.setDownloadState(DownloadTask.DownloadCancel);
				
				DownloadBatchUrl.getInstants().removeTask(task);
				
				tasks.remove(item.getId());
				
				clcItem.setDownloadState(CollectionItem.DownloadNone);
				
				CollectionItem.saveOrUpdate(clcItem);
			}
		}
	}
	
	/**
	 * 暂停下载
	 * @param item
	 */
	public static void pauseDownload(GameItem item) {
		
		MyLog.d(TAG, "pauseDownload...");

		synchronized (lock) {

			if (item != null && tasks.containsKey(item.getId())) {

				DownloadTask task = tasks.get(item.getId());

				task.setDownloadState(DownloadTask.DownloadPause);

				DownloadBatchUrl.getInstants().removeTask(task);

				tasks.remove(item.getId());
				
				MyLog.d(TAG, "pauseDownload...remove task gameId : " + item.getId());
				
				
				// 更新收藏列表状态
				int progress = GameDownload.getInitProgress(item);
				progress = progress >= 0 ? progress : 0;

				CollectionItem clcItem = CollectionItem.query(item.getId());
				if (clcItem == null) {
					return;
				}
				int state = clcItem.getDownloadState();
				MyLog.d(TAG, "pauseDownload...state : " + state);
				
				if(state==CollectionItem.DownloadDoing){
					clcItem.setDownProgress(progress);
					clcItem.setDownloadState(CollectionItem.DownloadPause);
					CollectionItem.saveOrUpdate(clcItem);
				}
				
				MyLog.d(TAG, "pauseDownload...save collection state gameId : " + item.getId());
				
			}
		}
	}
	
	public static void checkOutOfSpace(Context context,int progress, GameItem gameItem) {
		 long gameSize = gameItem.getSize();
		 long downloadedLength = FileUtils.getFolderSize(getRootPath(gameItem));
		 long needLength = (gameSize - downloadedLength) < 0?0:(gameSize - downloadedLength);
		 MyLog.d(TAG, "checkOutOfSpace need Length : " + FileConvertUtil.getMbGbFileSize(needLength));
		 MyLog.d(TAG, "checkOutOfSpace remain Length : " + FileConvertUtil.getMbGbFileSize(FileUtils.getSDCardFreeSpace()));
		boolean isOutOfSpace = FileUtils.checkOutOfSDCardSpace(needLength);
		if(isOutOfSpace/*true*/){
			List<Integer> gameIds = GameDownload.getAllDownloadingGameIds();
			MyLog.d(TAG, "checkOutOfSpace RealDoing gameIds size: " + gameIds.size());
			for(Integer gameId : gameIds){
				MyLog.d(TAG, "checkOutOfSpace RealDoing gameId : " + gameId);
				GameDownload.pauseDownload(GameItem.getGameById(gameId));
			}
			MemoryLessDialog memoryLessDialog = new MemoryLessDialog(context, gameSize);
			memoryLessDialog.show();
		}
	}

	/**
	 * 从下载任务中删除task
	 * @param gameItem
	 */
	public static void removeDownloadTask(GameItem gameItem){
		
		synchronized (lock) {
			
			int gameId = gameItem.getId();
			
			if(tasks.containsKey(gameId)){
				
				DownloadTask task = tasks.get(gameId);
				
				DownloadBatchUrl.getInstants().removeTask(task);
				
				tasks.remove(gameId);
				
				MyLog.d(TAG, "removeTask success gameId : " + gameId);
			}
			
		}
		
		
	}
	
	
	public static List<Integer> getAllDownloadingGameIds(){
		List<Integer> gameIds = new ArrayList<Integer>();
		 for (Map.Entry<Integer, DownloadTask> task : tasks.entrySet()) {
			 gameIds.add(task.getKey());
		 }
		 return gameIds;
	}



	static public int getDownloadProgress(GameItem item) {
		synchronized (lock) {
			if (item != null) {
				DownloadTask task = tasks.get(item.getId());
				if (task != null)
					return task.getProgress();
			}
		}
		return -1;
	}

	static public long getDownloadedBytes(GameItem item) {
		synchronized (lock) {
			if (item != null) {
				DownloadTask task = tasks.get(item.getId());
				if (task != null)
					return task.getDoneLen();
			}
		}
		return -1;
	}
	
    public static int getDownloadSpeed(){
    	return DownloadTask.getSpeed();
    }
    
    
	public static String getDownloadSpeedStr() {
		int speed = getDownloadSpeed();
		
		StringBuffer sb = new StringBuffer();
		
		boolean isNetAvailable = NetworkUtils.isNetworkAvailable(VRApplication
				.getAppContext());

		if (!isNetAvailable) {

			sb.append(0 + Constant.KB_PS);

			return sb.toString();

		}
		
    	if(speed < 1000){
    		
    		sb.append(speed + Constant.KB_PS);
    		
    	}else{
    		int speedM = speed/1000;
    		int speedK = (speed-speedM*1000)/100;
    		sb.append(speedM+"."+speedK + Constant.MB_PS);
    		
    	}
    	
    	return sb.toString();
	}
    
    
    public static String getDownloadedLengthStr(GameItem gameItem){
    	return FileConvertUtil.getMbGbFileSize(getGameDoneSize(gameItem));
    }
    
    public static String getTotalLengthStr(GameItem gameItem){
    	return FileConvertUtil.getMbGbFileSize(gameItem.getSize());
    }
    
   public static String getRatioLengthStr(GameItem gameItem){
   	return getDownloadedLengthStr(gameItem) + "/" + getTotalLengthStr(gameItem);
    }
    
    public static long getGameDoneSize(GameItem item){
        List<String> urlList = GameUrls(item);
        String savePath = getRootPath(item);
        long size = 0;
        for (String fname:urlList){
          String fileName = savePath+File.separator+FileUtils.getFileName(fname);
          String fileNameTmp = savePath+File.separator+FileUtils.getFileName(fname)+".tmp";
          
          File file = new File(fileName);
          if(file != null && file.exists()){
        	  size += file.length();
          }else{
        	  File fileTimp = new File(fileNameTmp);
        	  if(fileTimp != null && fileTimp.exists())
        		  size += fileTimp.length();
          }
        }
        return size;
      }
    
	
	/**
	 * 正在下载的重新下载
	 */
	public static void reDownloadGame(){
		
		MyLog.d(TAG, "reDownloadGame...");
		
		List<CollectionItem> clcItemList = CollectionItem.getAllNotDownloadedCollectionItems();
		
		if(clcItemList==null){
			return;
		}
		
		MyLog.d(TAG, "clcItemList " + clcItemList.toString());
		
		List<Integer> ids = new ArrayList<Integer>();
		
		
		for(CollectionItem clcItem:clcItemList){
			
			int state = clcItem.getDownloadState();
			if(state==CollectionItem.DownloadDoing||state==CollectionItem.DownloadError/* || state==CollectionItem.DownloadPause*/){
				
				
				
				ids.add(clcItem.getGameId());	
				
				MyLog.d(TAG, "ids " + ids);
				
			}
			
		}
		
		List<GameItem> gameItemList = GameItem.getGameListByIds(ids);
		
		if(gameItemList==null){
			
			return;
		}
		
		MyLog.d(TAG, "gameItemList size : " + gameItemList.size());
		
		Collections.reverse(gameItemList);
		
		for(GameItem gameItem:gameItemList){
			
			GameDownload.downloadGame(gameItem);
			
		}
			
	}
	
	

	
	
	private static HashMap<String, GameDdNotifyCallback> gameDdNotifyCenter = new HashMap<String,GameDdNotifyCallback>();
	
	/**
	 * 设置开始下载回调
	 * @param callback
	 * @param param
	 */
	public static void setGameDdNotify(GameDdNotifyCallback callback,String key){
		
		synchronized (nLock) {
			
			if(callback==null){
				
				gameDdNotifyCenter.remove(key);
				
			}else{
				
				gameDdNotifyCenter.put(key,callback);
			}
			
			
			
		}
	

		
	}
	
	/**
	 * 通知下载
	 */
	private static void gameDownNotify(GameItem gameItem){
		
		synchronized (nLock) {
			
			for(String key:gameDdNotifyCenter.keySet()){
				
				GameDdNotifyCallback notify = gameDdNotifyCenter.get(key);
				
				if(notify!=null){
					
					notify.startDownload(gameItem);
				}
				
			}
		
		}
		
		
	}
	
	//反馈下载进度
	public static void involkeGameProgress(Object params,int progress,int downloadState){
		synchronized (proLock) {
			
			for(String key:progressNotifies.keySet()){
				
				DownloadCallBack downloadCallback = progressNotifies.get(key);
				
				if(downloadCallback!=null){
					
					downloadCallback.progress(params, progress, downloadState);
				}
			}
		}
		GameItem gameItem = (GameItem) params;
		
		if(gameItem != null){
			
			MyLog.d(TAG, "involkeGameProgress gameId : " + gameItem.getId() + " downloadState : " + downloadState);
			//当成功或者失败从下载任务中删除task
			if(downloadState == DownloadTask.DownloadFailed || downloadState == DownloadTask.DownloadSuccess){
				removeDownloadTask(gameItem);
			}
			//TODO从下载到下载成功
			if(downloadState == DownloadTask.DownloadRealDoing || downloadState == DownloadTask.DownloadSuccess){
				GameDownloadBP.getInstants().saveGameDownloadBuried(gameItem, downloadState);
			}
		}
	}
	
	
	//设置下载进度回调
	public static void setGameProgressNotify(DownloadCallBack callBack, String key){
		synchronized(proLock) {
			if (callBack == null)
				progressNotifies.remove(key);
			else
				progressNotifies.put(key, callBack);
		}
	}
	
	//下载进度回调
	private static final Object proLock = new Object();
	
	//回调
	private static Map<String, DownloadCallBack> progressNotifies = new HashMap<String, DownloadCallBack>();
	
	//下载进度锁
	private static final Object dwLock = new Object();
	
	//存储下载进度 用于初始化
	private static Map<Integer,Integer> downProgress = new HashMap<Integer, Integer>();
	
	
	/**
	 * 获取初始化时的下载进度
	 * @param gameItem
	 * @return
	 */
	public static int getInitProgress(GameItem gameItem){
		
		int progress = getRunningProgress(gameItem.getId());
		MyLog.e(TAG, "getRunningProgress ： " + progress);
		if(-1==progress){
			
			CollectionItem clcItem = CollectionItem.query(gameItem.getId());
			
			if(clcItem==null){
				MyLog.e(TAG, "clcItem == null");
				return 0;
			}
			
			long totalLen = clcItem.getTotalLen();
			
			if(totalLen==0){
				MyLog.e(TAG, "totalLen == 0");
				return 0;
			}
			
			long curLen = 0;
			
			for(String res:GameRes(gameItem)){
				
				String savePath = getRootPath(gameItem)+"/"+res;
				
				File file = new File(savePath);
				
				if(file.exists()){
					
					curLen += file.length();
					
				}else{
					
					file = new File(savePath+".tmp");
					
					if(file.exists()){
						
						curLen += file.length();
					}
					
				}
					
			}
			
			
			
			progress = (int) (curLen*100/totalLen);
			
			MyLog.e(TAG, "caculat progress ： " + progress);
			
			if(progress>=100){
				
				progress = 0;
			}
			
			MyLog.e(TAG, "caculat progress 11： " + progress);
			
			//更新运行时进度
			setRunningProgresss(gameItem.getId(), progress);
				
			
		}
		
		if(progress>=100){
			
			progress = 0;
		}		
		return progress;
	}
	
	/**
	 * 获取运行时进度
	 * @param gameItem
	 * @return
	 */
	private static int getRunningProgress(int gameId){
		
		int progress = -1;
		
		synchronized (dwLock) {
			
			if(downProgress.containsKey(gameId)){
				
				progress = downProgress.get(gameId);
			}
		}
		
		return progress;
	}
	
	public static void setRunningProgresss(int gameId,int progress){
		
		synchronized (dwLock) {
			if(progress > 0){
				downProgress.put(gameId, progress);
			}
		}
	}
	
	/**
	 * 删除进度
	 * @param gameId
	 */
	public static void rmRunningProgress(int gameId){
		
		synchronized (dwLock) {
			
			downProgress.remove(gameId);
		}
	}
	
	public static void sortFavoritesGames(List<GameItem> gameList){
		if (gameList == null || gameList.size() == 0)
			return;
		List<GameItem> waiting = new ArrayList<GameItem>();
		List<GameItem> pause = new ArrayList<GameItem>();
		//List<GameItem> errors = new ArrayList<GameItem>();
		List<GameItem> none = new ArrayList<GameItem>();
		GameItem nowDownloading = null;
		for (GameItem item: gameList){
			CollectionItem citem = CollectionItem.query(item.getId());
			if (citem == null)
				continue;
			if (citem.getDownloadState() == CollectionItem.DownloadDoing && !GameDownload.isDownloadWaiting(item)){
				nowDownloading = item;
				continue;
			}
			if (citem.getDownloadState() == CollectionItem.DownloadDoing ||
					citem.getDownloadState() == CollectionItem.DownloadError){
				waiting.add(item);
			}else if (citem.getDownloadState() == CollectionItem.DownloadPause){
				pause.add(item);
			}else{
				none.add(item);
			}
		}
		gameList.clear();
		if (nowDownloading != null)
			gameList.add(nowDownloading);
		if (!waiting.isEmpty())
			gameList.addAll(waiting);
		if (!pause.isEmpty())
			gameList.addAll(pause);
		if (!none.isEmpty())
			gameList.addAll(none);
	}
	
}
